from flask import Response, jsonify, Flask, request, Blueprint,url_for
from configs import *
from modules.Tables import *
from sqlalchemy import func



# 创建蓝图，对应的register目录（激活操作视图）
video_view = Blueprint('video', __name__)


def get_rtsp_url(em_data, par_id_ip=None, is_history=False, start_time=None, end_time=None):
    """
    生成 RTSP URL
    :param em_data: 摄像头设备数据
    :param par_id_ip: 父设备 IP 数据
    :param is_history: 是否为历史回放
    :param start_time: 回放起始时间（仅录像机）
    :param end_time: 回放结束时间（仅录像机）
    :return: 生成的 RTSP URL
    """
    if is_history:
        # 历史回放
        if par_id_ip:
            return "rtsp://{}:{}@{}:554/Streaming/tracks/{}starttime={}z&endtime={}z".format(
                urllib.parse.quote(em_data.equipment_uname),
                urllib.parse.quote(em_data.equipment_password),
                urllib.parse.quote(par_id_ip.equipment_ip),
                urllib.parse.quote(em_data.code),
                start_time,
                end_time,
            )
        else:
            return ""
    else:
        # 实时视频
        if par_id_ip:
            return "rtsp://{}:{}@{}:554/Streaming/Unicast/Channels/{}".format(
                urllib.parse.quote(em_data.equipment_uname),
                urllib.parse.quote(em_data.equipment_password),
                urllib.parse.quote(par_id_ip.equipment_ip),
                urllib.parse.quote(em_data.code),
            )
        else:
            return "rtsp://{}:{}@{}".format(
                urllib.parse.quote(em_data.equipment_uname),
                urllib.parse.quote(em_data.equipment_password),
                urllib.parse.quote(em_data.equipment_ip),
            )

# 实时视频推流接口（视频分析）
@video_view.route('/real_time_video', methods=['GET'])
# @jwt_required()
def real_time_video():
    """
    实时视频推流接口

    参数:
        model_path (str): 模型id
        linux_ip (str): RTMP 服务器 IP 地址。
        rtsp_url (str): RTSP 流媒体源地址。
        width (str): 视频宽度。
        height (str): 视频高度。
        frame_r (str): 比特率。
        baud_b (str): 帧率。
        stream_data_flag (str): 运行标识   1运行  0 删除。
        video_type (str): 运行标识   1 实时视频  2录像回放
        start_time (str): 开始时间
        end_time (str):   结束时间
    """

    # 视频分析列表
    data_list=[]

    rtmp_server_ip=DB_HOST
    em_id = strip_whitespace(request.args.get('em_id',None) ) # 摄像头id
    width = strip_whitespace(request.args.get('width',1920))  # 视频宽度
    height = strip_whitespace(request.args.get('height',1080))  # 视频高度
    frame_r = strip_whitespace(request.args.get('frame_r',1000))  # 比特率
    baud_b = strip_whitespace(request.args.get('baud_b',25))  # 帧率
    stream_data_flag = strip_whitespace(request.args.get('stream_data_flag',None))  # 运行标识  1运行  3 删除
    video_status = strip_whitespace(request.args.get('video_status','1'))  # 运行标识   1 实时视频  2录像回放
    start_time = strip_whitespace(request.args.get('start_time',None))  # 运行标识   开始时间
    end_time = strip_whitespace(request.args.get('end_time',None))  # 运行标识   结束时间
    model_id = strip_whitespace(request.args.get('model_id',None))  # 模型id


    # 参数构建判断是否为空
    params = [rtmp_server_ip, em_id, width, height, frame_r, baud_b, stream_data_flag,model_id]

    if not all(params):
        return jsonify({'code': 400, 'msg': '设备数据有未填写项'})

    r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=3)

    # 获取模型路径
    model_path = db.session.query(Algorithm_library).filter(Algorithm_library.id==model_id).first()
    if not model_path:
        return jsonify({'code': 400, 'msg': '该模型不存在!'})

    parsed_em_id = safe_eval(em_id)
    if parsed_em_id is not None:
        print("成功解析 em_id:", parsed_em_id)
        for i in eval(em_id):
            rtsp_url = ''
            em_data = db.session.query(Equipment).filter(Equipment.id == i).first()

            # 如果设备数据存在
            if em_data:
                # 判断设备类型
                if em_data.equipment_type == '安防平台':
                    rtsp_url = em_data.Hik_rtsp_url
                elif em_data.equipment_type == '安防平台' and video_status == '2':
                    return jsonify({'code':400,'msg':'安防平台回放无法播放！'})
                else:
                    # 获取父设备信息（若存在）
                    par_id_ip = None
                    if em_data.VCR_data_id and em_data.parent_id:
                        par_id_ip = db.session.query(Equipment).filter(Equipment.id == em_data.parent_id).first()

                    # 根据 video_status 生成对应 RTSP URL
                    is_history = (video_status != '1')
                    rtsp_url = get_rtsp_url(em_data, par_id_ip, is_history, start_time, end_time)

                    # 如果无法生成有效的 RTSP URL，返回错误
                    if not rtsp_url:
                        return jsonify({'code': 400, 'msg': '无法生成有效的 RTSP 流 URL!'})

                    print(f"生成的 RTSP URL: {rtsp_url}")

                    def extract_ip_from_rtsp(rtsp_url):
                        """从 RTSP URL 中提取 IP 地址"""
                        match = re.search(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', rtsp_url)
                        if match:
                            return match.group(1)
                        else:
                            return None

                    try:
                        # 提取 IP 地址
                        ip_address = extract_ip_from_rtsp(rtsp_url)
                        print(f"提取的 IP 地址: {ip_address}")

                        pinger = Pinger(target_host=ip_address)
                        delay = pinger.ping_once()

                        # 如果延迟为 None，表示设备不可达
                        if delay is None:
                            return jsonify({'code': 400, 'msg': '当前监控点不在线!'})
                    except Exception as e:
                        # 捕获异常并返回错误
                        return jsonify({'code': 400, 'msg': '当前监控点不在线!'})

                # 构建要推送的数据
                data_to_set = {
                    "rtsp_url": rtsp_url,
                    "rtmp_server_ip": rtmp_server_ip,
                    "width": width,
                    "height": height,
                    "frame_r": frame_r,
                    "baud_b": baud_b,
                    "stream_data_flag": stream_data_flag,
                    "model_path": model_path.algorithm_path,
                }

                # 将数据添加到列表
                data_list.append(data_to_set)

                print(f"当前 data_list: {data_list}")

                # 数据序列自增，并添加 flv_url
                for index, item in enumerate(data_list, start=1):
                    item['id'] = index
                    item['flv_url'] = f'http://{rtmp_server_ip}:8080/live/stream{index}.flv'

                # 将数据保存到 Redis
                r3.set('video_data_list', str(data_list))

                # 返回成功响应
                # return jsonify({'code': 200, 'msg': '推流成功', 'flv_data': data_list})

            else:
                # 如果设备数据不存在，返回错误
                return jsonify({'code': 400, 'msg': '设备不存在!'})
        r3.set('stream_data_flag', 1)
    else:

        return jsonify({'code': 400, 'msg': '无法解析'})



    return jsonify({'code': 200, 'msg': '推流成功', 'flv_data': data_list})


# # 实时视频推流接口（视频分析）
# @video_view.route('/real_time_video', methods=['GET'])
# # @jwt_required()
# def real_time_video():
#     """
#     实时视频推流接口
#
#     参数:
#         model_path (str): 模型id
#         linux_ip (str): RTMP 服务器 IP 地址。
#         rtsp_url (str): RTSP 流媒体源地址。
#         width (str): 视频宽度。
#         height (str): 视频高度。
#         frame_r (str): 比特率。
#         baud_b (str): 帧率。
#         stream_data_flag (str): 运行标识   1运行  0 删除。
#         video_type (str): 运行标识   1 实时视频  2录像回放
#         start_time (str): 开始时间
#         end_time (str):   结束时间
#     """
#
#     # 视频分析列表
#     data_list=[]
#
#
#     rtmp_server_ip=DB_HOST
#     em_id = strip_whitespace(request.args.get('em_id',None) ) # 摄像头id
#     width = strip_whitespace(request.args.get('width',1920))  # 视频宽度
#     height = strip_whitespace(request.args.get('height',1080))  # 视频高度
#     frame_r = strip_whitespace(request.args.get('frame_r',1000))  # 比特率
#     baud_b = strip_whitespace(request.args.get('baud_b',25))  # 帧率
#     stream_data_flag = strip_whitespace(request.args.get('stream_data_flag',None))  # 运行标识  1运行  3 删除
#     video_status = strip_whitespace(request.args.get('video_status','1'))  # 运行标识   1 实时视频  2录像回放
#     start_time = strip_whitespace(request.args.get('start_time',None))  # 运行标识   开始时间
#     end_time = strip_whitespace(request.args.get('end_time',None))  # 运行标识   结束时间
#     model_id = strip_whitespace(request.args.get('model_id',None))  # 模型id
#
#     rtsp_url = ''
#     # 参数构建判断是否为空
#     params = [rtmp_server_ip, em_id, width, height, frame_r, baud_b, stream_data_flag,model_id]
#
#     if not all(params):
#         return jsonify({'code': 400, 'msg': '设备数据有未填写项'})
#
#     r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=3)
#
#     # 获取模型路径
#     model_path = db.session.query(Algorithm_library).filter(Algorithm_library.id==model_id).first()
#     if not model_path:
#         return jsonify({'code': 400, 'msg': '该模型不存在!'})
#
#     # 获取摄像头信息
#     em_data = db.session.query(Equipment).filter(Equipment.id == em_id).first()
#     print(em_data,'111111')
#
#     if em_data:
#         if em_data.equipment_type == '安防平台':
#             rtsp_url = em_data.Hik_rtsp_url
#         else:
#
#             # 获取父设备信息（若存在）
#             par_id_ip = None
#             if em_data.VCR_data_id and em_data.parent_id:
#                 par_id_ip = db.session.query(Equipment).filter(Equipment.id == em_data.parent_id).first()
#
#             # 根据 video_status 生成对应 RTSP URL
#             is_history = (video_status != '1')
#             rtsp_url = get_rtsp_url(em_data, par_id_ip, is_history, start_time, end_time)
#
#             if not rtsp_url:
#                 return jsonify({'code': 400, 'msg': '无法生成有效的 RTSP 流 URL!'})
#
#             print("生成的 RTSP URL:", rtsp_url)
#
#             def extract_ip_from_rtsp(rtsp_url):
#                 """从 RTSP URL 中提取 IP 地址"""
#                 # 使用正则表达式匹配 IP 地址
#                 match = re.search(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', rtsp_url)
#
#                 if match:
#                     return match.group(1)
#                 else:
#                     return None
#
#             try:
#                 # 提取ip
#                 ip_address = extract_ip_from_rtsp(rtsp_url)
#                 print("提取的 IP 地址:", ip_address)
#
#                 pinger = Pinger(target_host=ip_address)
#                 delay = pinger.ping_once()
#                 if delay == None:
#                     return jsonify({'code': 400, 'msg': '当前监控点不在线!'})
#             except Exception as e:
#                     return jsonify({'code': 400, 'msg': '当前监控点不在线!'})
#
#         # 定义一个字典来保存要设置的键值对
#         data_to_set = {
#             "rtsp_url": rtsp_url,
#             "rtmp_server_ip": rtmp_server_ip,
#             "width": width,
#             "height": height,
#             "frame_r": frame_r,
#             "baud_b": baud_b,
#             "stream_data_flag": stream_data_flag,
#             "model_path": model_path.algorithm_path,
#         }
#
#         data_list.append(data_to_set)
#
#         # 使用 r3 直接设置每个键值对
#         for key, value in data_to_set.items():
#             print(f"设置 {key} = {value} 到 r3")  # 打印设置内容
#             r3.set(key, value)
#
#         return jsonify({'code': 200,'msg':'推流成功','flv_url':'http://{}:8080/live/stream.flv'.format(rtmp_server_ip)})
#     else:
#         return jsonify({'code':400,'msg':'设备不存在!'})


# 实时视频状态检测（视频分析）
@video_view.route('/real_time_video_status', methods=['GET'])
@jwt_required()
@jwt_required_with_refresh
def real_time_video_status():
    r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=3)
    video_type = r3.get('video_type')
    if video_type == '1':
        return jsonify({'code': 200, 'video_type': video_type})
    else:
        return jsonify({'code': 201, 'video_type':'视频分析停止'})


# 实时视频停止推流（视频分析）
@video_view.route('/real_time_video_stop', methods=['GET'])
@jwt_required()
@jwt_required_with_refresh
def real_time_video_stop():
    r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=3)
    r3.set('stream_data_flag',3)
    return jsonify({'code': 200, 'video_type':'视频分析停止'})


# 报警视频停止推流（视频分析）
@video_view.route('/alg_video_stop', methods=['GET'])
@jwt_required()
@jwt_required_with_refresh
def alg_video_stop():
    r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=4)
    r3.set('stream_data_flag',3)
    return jsonify({'code': 200, 'video_type':'视频分析停止'})



# 报警配置视频推送（视频分析）
@video_view.route('/alg_conf_video', methods=['GET'])
# @jwt_required()
def alg_conf_video():
    """
    报警配置视频推送

    参数:
        rtmp_server_ip (str): RTMP 服务器 IP 地址。
        config_id：算法配置id
        rtsp_url (str): RTSP 流媒体源地址。
        width (str): 视频宽度。
        height (str): 视频高度。
        frame_r (str): 比特率。
        baud_b (str): 帧率。
        stream_data_flag (str): 运行标识   1运行  0 删除。
    """

    rtmp_server_ip=DB_HOST
    config_id = strip_whitespace(request.args.get('config_id',None))  # 视频宽度
    width = strip_whitespace(request.args.get('width',1080))  # 视频宽度
    height = strip_whitespace(request.args.get('height',1920))  # 视频高度
    frame_r = strip_whitespace(request.args.get('frame_r',1300))  # 比特率
    baud_b = strip_whitespace(request.args.get('baud_b',6))  # 帧率
    stream_data_flag = strip_whitespace(request.args.get('stream_data_flag',0))  # 运行标识  1运行  3 删除


    # 参数构建判断是否为空
    params = [rtmp_server_ip, config_id, width, height, frame_r, baud_b, stream_data_flag]

    if not all(params):
        return jsonify({'code': 400, 'msg': '设备数据有未填写项'})

    r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=4)

    # 定义一个字典来保存要设置的键值对
    data_to_set = {
        "config_id":config_id,
        "rtmp_server_ip": rtmp_server_ip,
        "width": width,
        "height": height,
        "frame_r": frame_r,
        "baud_b": baud_b,
        "stream_data_flag": stream_data_flag,
        "video_type":3,
    }

    # 使用 r3 直接设置每个键值对
    for key, value in data_to_set.items():
        print(f"设置 {key} = {value} 到 r3")  # 打印设置内容
        r3.set(key, value)

    return jsonify({'code':200,'message':'配置监控点检测进行中'})


# 报警配置视频状态检测（视频分析）
@video_view.route('/alg_status_video', methods=['GET'])
def alg_status_video():
    r3 = redis.Redis(host=Redis_ip, port=Redis_port, password=Redis_password, decode_responses=True, db=4)
    video_type = r3.get('video_type')
    if video_type == '1':
        return jsonify({'code': 200, 'video_type': video_type})
    elif video_type=='2':
        return jsonify({'code': 201, 'video_type': video_type})
    else:
        return jsonify({'code':203,'video_type':video_type})


# 报警列表监控点录像机ip，账密，通道号返回接口（视频分析）
@video_view.route('/video_playback', methods=['GET'])
def video_playback():
    # 查询监控点id
    id = strip_whitespace(request.args.get('id',None))

    # 初始化
    data_info={}

    # 查询设备信息
    equipment_data = db.session.query(Equipment).filter(Equipment.id==id,Equipment.parent_id!=None).first()

    # 如果没有查询到设备信息返回
    if not equipment_data:
        return jsonify({'code':400,'msg':'该监控点不存在！'})

    # 查询到设备信息，当前类型为录像机的时候做判断
    if equipment_data.equipment_type == '录像机':
        equipment_parent_data = db.session.query(Equipment).filter(Equipment.id==equipment_data.parent_id).first()

        # 返回对应回放需要参数
        data_info={
            'equipment_aisles':equipment_data.equipment_aisles,
            'equipment_ip':equipment_parent_data.equipment_ip,
            'equipment_uname':equipment_parent_data.equipment_uname,
            'equipment_password':equipment_parent_data.equipment_password,
                   }

    # 后续判断安防平台信息

    return jsonify({'code':200,'data':data_info})




